from machine import Pin
import time

class NEC_IR:
    KeyMap = {
        '0xa2': 'Switch',
        '0xe2': 'MENU',
        '0x22': 'TEST',
        '0x2': '+',
        '0xc2': 'Return',
        '0xe0': '<<',
        '0xa8': 'play',
        '0x90': '>>',
        '0x98': '-',
        '0xb0':'del',
        '0x68':'0',
        '0x30':'1',
        '0x18':'2',
        '0x7a':'3',
        '0x10':'4',
        '0x38':'5',
        '0x5a':'6',
        '0x42':'7',
        '0x4a':'8',
        '0x52':'9'
        }
    
    def __init__(self, pin:int):
        self.IR_PIN = Pin(pin, Pin.IN, Pin.PULL_UP)
        self.code = [0, 0, 0, 0]    # 存放解码数据
        self.repeat = 0             # 重复数据标识
    
    def ir_decode(self):
        # 常态保持高电平
        while self.IR_PIN.value():
            continue
        # 判断起始码是否有效，9ms低电平
        count = 0
        while not self.IR_PIN.value():
            count = count + 1
            time.sleep_ms(1)
        if count < 8:
            return None
        # 判断新数据还是重复数据
        count = 0
        while self.IR_PIN.value():
            count = count + 1
            time.sleep_us(1)
        if count > 100 and count < 225:
            self.repeat = 1
            return True
        
        elif count > 250 and count < 400 :
            # 解码新数据
            self.repeat = 0
            raw = []
            for m in range(32):
                while not self.IR_PIN.value():
                    continue
                count = 0
                while self.IR_PIN.value():
                    time.sleep_us(100)
                    count = count + 1
                if count > 4 and count < 7:
                    raw.append(0)
                else:
                    raw.append(1)
        
            # 从raw中提取地址、地址反码、命令、命令反码
            addr = 0
            re_addr = 0
            command = 0
            re_command = 0
            for k,v in enumerate(raw[0:8]):
                addr = addr + (v << (8-k-1))
        
            for k,v in enumerate(raw[8:16]):
                re_addr = re_addr + (v << (8-k-1))
        
            for k,v in enumerate(raw[16:24]):
                command = command + (v << (8-k-1))
        
            for k,v in enumerate(raw[24:32]):
                re_command = re_command + (v << (8-k-1))
            # 校验地址和命令是否正确
            if hex(addr + re_addr) != '0xff':
                return None
            if hex(command + re_command) != '0xff':
                return None
            # 将数据写入DATA中
            self.code[0] = hex(addr)
            self.code[1] = hex(re_addr)
            self.code[2] = hex(command)
            self.code[3] = hex(re_command)
            return True
        else:
            return None
    
    def ir_read(self):
        return self.KeyMap[self.code[2]]
